package com.demo.security.service.impl;

import cn.hutool.crypto.asymmetric.KeyType;
import cn.hutool.crypto.asymmetric.RSA;
import com.demo.common.redis.service.RedisService;
import com.demo.security.service.EncryptTransferService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.Assert;
import org.springframework.util.DigestUtils;

import java.time.Duration;
import java.util.Objects;
import java.util.concurrent.TimeUnit;

/**
 * 密码加密传输服务
 *
 * @author molong
 * @since 2024/6/7
 */
@Component
public class EncryptTransferServiceImpl implements EncryptTransferService {

    private final Logger LOGGER = LoggerFactory.getLogger(EncryptTransferServiceImpl.class);
    private final RedisService redisService;

    private final static String REDIS_KEY = "COM:DEMO:FRAMEWORK:RSA:";

    @Autowired(required = false)
    public EncryptTransferServiceImpl(RedisService redisService) {
        this.redisService = redisService;
    }

    @Override
    public String getPublicKey() {
        return getPublicKey(getDelayTime());
    }

    @Override
    public String decrypt(String encryptContent, String publicKey) {
        String privateKey = getPrivateKey(publicKey);
        Assert.notNull(privateKey, "RSA private key is empty ");
        destroy(publicKey);
        RSA rsa = new RSA(privateKey, publicKey);
        byte[] passwordHex = rsa.decrypt(encryptContent, KeyType.PrivateKey);
        return new String(passwordHex);
    }

    /**
     * 组装redis的key
     * @param publicKey 公钥
     * @return 组装结果
     */
    private String buildRedisKey(String publicKey) {
        return REDIS_KEY + DigestUtils.md5DigestAsHex(publicKey.getBytes());
    }

    /**
     * 立即根据KEY删除此条数据,不需要等到定时器时间到了再删除
     *
     * @param key 需要删除的数据KEY
     */
    public void destroy(String key) {
        redisService.del(buildRedisKey(key));
    }
    @Override
    public String getPublicKey(Duration delay) {
        RSA rsa = new RSA();
        String publicKey = rsa.getPublicKeyBase64();
        LOGGER.debug("Generate public key:{}", publicKey);
        LOGGER.debug("Generate private key:{}", rsa.getPrivateKeyBase64());
        String privateKey = rsa.getPrivateKeyBase64();
        redisService.set(buildRedisKey(publicKey), privateKey, delay.getSeconds());
        return publicKey;
    }

    @Override
    public String getPrivateKey(String publicKey) {
        Object obj=redisService.get(buildRedisKey(publicKey));
        if(Objects.isNull(obj)){
            return null;
        }
        return obj.toString();
    }

    /**
     * 数据超时清理时间,使用{@link Duration}进行时间配置
     *
     * @return 超时时间
     */
    public Duration getDelayTime() {
        return Duration.ofMinutes(30);
    }
}
